
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "audio_error.h"
#include "audio_element.h"
#include "audio_mem.h"
#include "audio_type_def.h"

#include "record_filter.h"
#include "istetho3_filter.h"

// #include "driver/uart.h"

// #include "esp_filter.h"

#define FILTER_INBUFFER_LENGTH       (500)

static const char *TAG = "BPFLT";
static esp_err_t record_filter_open(audio_element_handle_t self)
{
    // const unsigned char Tags[4] = {0xAA, 0x55, 0x90, 0x01};  // 0x0190 = 400 byte
    // uart_write_bytes(UART_NUM_0, (char *)Tags, 4);

    filter_bandpass_set_t *vol_setup_info = (filter_bandpass_set_t *)audio_element_getdata(self);
    vol_setup_info->set_flag = 0;
    vol_setup_info->in_buf = audio_calloc(1, FILTER_INBUFFER_LENGTH);
    if(vol_setup_info->in_buf == NULL){
        ESP_LOGE(TAG, "audio_calloc failed for in_buf. (line %d)", __LINE__);
        return ESP_ERR_NO_MEM;
    }
    vol_setup_info->handle = bpfilter_open(vol_setup_info->type);
    if(vol_setup_info->handle == NULL){
        ESP_LOGE(TAG, "Failed to create FILTER handle. (line %d)", __LINE__);
        return ESP_FAIL;
    }
    ESP_LOGI(TAG, "record_filter_open successful. audioinfo--> type:%d, set_flag:%d, chls:%d", vol_setup_info->type, vol_setup_info->set_flag, vol_setup_info->channel);
    return ESP_OK;
}

static esp_err_t record_filter_close(audio_element_handle_t self)
{
    filter_bandpass_set_t *vol_setup_info = (filter_bandpass_set_t *)audio_element_getdata(self);
    bpfilter_close(vol_setup_info->handle);
    if (vol_setup_info->in_buf) {
        audio_free(vol_setup_info->in_buf);
        vol_setup_info->in_buf = NULL;
    }
    ESP_LOGI(TAG, "record_filter_close successful.");
    return ESP_OK;
}

uint32_t record_send_data(char *buffer, int wanted_size);
short g_iRecordBuf[518];
static esp_err_t record_filter_process(audio_element_handle_t self, char *in_buffer, int in_len)
{
    int i = 0;
    filter_bandpass_set_t *vol_setup_info = (filter_bandpass_set_t *)audio_element_getdata(self);
    int len = audio_element_input(self, (char *)vol_setup_info->in_buf, FILTER_INBUFFER_LENGTH);
    if (len < 0) {
        return len; 
    }
    if (vol_setup_info->set_flag == 1) {
        record_filter_close(self);
        record_filter_open(self);
        ESP_LOGI(TAG, "Reopen record_filter");
        return ESP_CODEC_ERR_CONTINUE;
    }

    // 左右通道的数据数据数据分离处理并分别滤波应该放到带通滤波器处理函数里面
    short *ptrBuf = (short *)vol_setup_info->in_buf;
    for (i = 0; i<(len/4); i++) {
        g_iRecordBuf[i] = ptrBuf[2*i+1];
    }
   
    record_send_data((char *)g_iRecordBuf, len/2);
    // uart_write_bytes(UART_NUM_0, (char *)g_iRecordBuf, len/2);
    /* 
    int ret = bpfilter_process((char *)vol_setup_info->in_buf, len,
                                       vol_setup_info->channel, vol_setup_info->handle, vol_setup_info->type);
    */
    len = audio_element_output(self, (char *)vol_setup_info->in_buf, len);
    return len;
}

void record_filter_set_channel(audio_element_handle_t self, int channel)
{
    filter_bandpass_set_t *vol_setup_info = (filter_bandpass_set_t *)audio_element_getdata(self);
    vol_setup_info->channel = channel;
    vol_setup_info->set_flag = 1;
}

void record_filter_set_type(audio_element_handle_t self, int type)
{
    filter_bandpass_set_t *vol_setup_info = (filter_bandpass_set_t *)audio_element_getdata(self);
    vol_setup_info->type = type;
    vol_setup_info->set_flag = 1;
}

int record_filter_get_type(audio_element_handle_t self)
{
    filter_bandpass_set_t *vol_setup_info = (filter_bandpass_set_t *)audio_element_getdata(self);
    return vol_setup_info->type;
}

static esp_err_t record_filter_destroy(audio_element_handle_t self)
{
    filter_bandpass_set_t *vol_setup_info = (filter_bandpass_set_t *)audio_element_getdata(self);
    if(vol_setup_info){
        audio_free(vol_setup_info);
    }
    return ESP_OK;   
}

audio_element_handle_t record_filter_init(record_filter_cfg_t *config)
{
    if (config == NULL) {
        ESP_LOGE(TAG, "config is NULL. (line %d)", __LINE__);
        return NULL;
    }
    filter_bandpass_set_t *vol_setup_info = audio_calloc(1, sizeof(filter_bandpass_set_t));
    AUDIO_MEM_CHECK(TAG, vol_setup_info, return NULL);
    audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG();
    audio_element_handle_t el;
    cfg.open = record_filter_open;
    cfg.close = record_filter_close;
    cfg.process = record_filter_process;
    cfg.destroy = record_filter_destroy;
    cfg.task_stack = config->task_stack;
    cfg.task_prio = config->task_prio;
    cfg.task_core = config->task_core;
    cfg.out_rb_size = config->out_rb_size;
    cfg.tag = "record_filter";
    el = audio_element_init(&cfg);
    AUDIO_MEM_CHECK(TAG, el, {audio_free(vol_setup_info); return NULL;});
    vol_setup_info->channel = config->channel;
    vol_setup_info->type = config->type;
    audio_element_setdata(el, vol_setup_info);
    ESP_LOGI(TAG, "record_filter_init successful.");
    return el;
}

